package wechat

import (
	"context"
	"encoding/xml"
	"gitee.com/Cauchy_AQ/vxopen/api/internal/svc"
	"gitee.com/Cauchy_AQ/vxopen/api/internal/types"
	"gitee.com/Cauchy_AQ/vxopen/rpc/wechat/wechat"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

type EventLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewEventLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EventLogic {
	return &EventLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *EventLogic) Event(req *types.EventReq) (resp string, err error) {
	err = verifySignatureSha1(req.Timestamp, req.Nonce, req.Signature)
	if err != nil {
		return "", err
	}

	// 不同事件的 rpc 触发
	if req.Event == "SCAN" {
		// 1. 扫码事件
		return l.EventScan(req)
	} else if req.Event == "subscribe" {
		// 2. 关注事件
		return l.EventSubscribe(req)
	} else if req.Event == "unsubscribe" {
		// 3. 取关事件
		return l.EventUnsubscribe(req)
	}

	return "success", nil
}

// EventScan 已关注用户的扫码事件
func (l *EventLogic) EventScan(req *types.EventReq) (string, error) {
	_, err := l.svcCtx.Wechat.ScanQrcode(l.ctx, &wechat.ScanQrcodeReq{
		Openid: req.Openid,
		Ticket: req.Ticket,
	})
	if err != nil {
		return "", err
	}
	return "success", nil
}

// EventSubscribe 新用户的关注事件
func (l *EventLogic) EventSubscribe(req *types.EventReq) (string, error) {
	respRpc, err := l.svcCtx.Wechat.Subscribe(l.ctx, &wechat.SubscribeReq{
		Openid:       req.Openid,
		ToUserName:   req.Tousername,
		FromUserName: req.Fromusername,
		CreateTime:   req.Createtime,
		Ticket:       req.Ticket,
	})
	if err != nil {
		return "", err
	}

	// 回复文本消息
	textResp := types.TextMsg{
		ToUserName:   types.CDATA(respRpc.ToUserName),
		FromUserName: types.CDATA(respRpc.FromUserName),
		CreateTime:   time.Now().Unix(),
		MsgType:      types.CDATA(respRpc.MsgType),
		Content:      types.CDATA(respRpc.Content),
	}
	b, _ := xml.MarshalIndent(textResp, "", "    ")

	return string(b), nil
}

// EventUnsubscribe 已关注用户的取关事件
func (l *EventLogic) EventUnsubscribe(req *types.EventReq) (string, error) {
	_, err := l.svcCtx.Wechat.Unsubscribe(l.ctx, &wechat.UnsubscribeReq{
		Openid: req.Openid,
	})
	if err != nil {
		return "", err
	}
	return "success", nil
}
